package com.dhcc.bpm.modules.sandbox.controller;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.dhcc.bpm.common.annotation.Log;
import com.dhcc.bpm.common.enums.BusinessType;
import com.dhcc.bpm.common.text.Convert;
import com.dhcc.bpm.modules.common.entity.Plupload;
import com.dhcc.bpm.modules.common.entity.Upload;
import com.dhcc.bpm.modules.common.service.IPluploadService;
import com.dhcc.bpm.modules.sandbox.entity.ApiReturn;
import com.dhcc.bpm.modules.sandbox.entity.CaseApiReturn;
import com.dhcc.bpm.modules.sandbox.entity.OpcSandboxCodeExpress;
import com.dhcc.bpm.modules.sandbox.entity.ReturnCode;
import com.dhcc.bpm.modules.sandbox.service.IApiReturnService;
import com.dhcc.bpm.modules.sandbox.service.ICaseApiReturnService;
import com.dhcc.bpm.modules.sandbox.service.IOpcSandboxCodeExpressService;
import com.dhcc.bpm.modules.sandbox.service.IReturnCodeService;
import com.dhcc.bpm.modules.sandbox.vo.ReturnCodeVO;
import com.dhcc.bpm.modules.system.service.ISerialNumberService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springblade.core.boot.ctrl.BladeController;
import org.springblade.core.log.annotation.ApiLog;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.Func;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @ClassName ReturnCodeController
 * @Description 返回码表 控制器
 * @Author sjm
 * @Date 2020/2/21 0021 15:16
 * @Version V1.0
 * @Copyright: 2020 东华软件 . All rights reserved.
 **/
@RestController
@AllArgsConstructor
@RequestMapping("bpm-sandbox/returnCode")
@Api(value = "返回码表", tags = "返回码表接口")
public class ReturnCodeController extends BladeController {
    private final static Logger log = LoggerFactory.getLogger(ReturnCodeController.class);
    private IReturnCodeService returnService;
    private IOpcSandboxCodeExpressService opcSandboxCodeExpressService;
    private ISerialNumberService serialNumberService;
    private IApiReturnService apiReturnService;
    private ICaseApiReturnService caseApiReturnService;
    @Autowired
    private IPluploadService pluploadService;

    /**
     * @param returnCode
     * @return org.springblade.core.tool.api.R<com.dhcc.bpm.modules.sandbox.entity.ReturnCode>
     * @Description 详情
     * @Author sjm
     * @Date 21:29 2020/2/21 0021
     **/
    @GetMapping("/detail")
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "详情", notes = "传入return")
    @ApiLog("报文列表详情")
    @Log(title = "报文列表详情", businessType = BusinessType.SELECT)
    public R<ReturnCode> detail(ReturnCode returnCode) {
        ReturnCode detail = returnService.getCodeById(returnCode.getId());
        return R.data(detail);
    }

    /**
     * @param returnCode
     * @param query
     * @return org.springblade.core.tool.api.R<com.baomidou.mybatisplus.core.metadata.IPage < com.dhcc.bpm.modules.sandbox.entity.ReturnCode>>
     * @Description 分页 返回码表
     * @Author sjm
     * @Date 21:29 2020/2/21 0021
     **/
    @GetMapping("/list")
    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "分页", notes = "传入return")
    @ApiLog("报文列表")
    @Log(title = "报文列表", businessType = BusinessType.SELECT)
    public R<IPage<ReturnCode>> list(@ApiIgnore @RequestParam Map<String, Object> returnCode, Query query) {
        IPage<ReturnCode> pages = returnService.page(Condition.getPage(query), Condition.getQueryWrapper(returnCode, ReturnCode.class));
        return R.data(pages);
    }

    /**
     * @param returnVo
     * @param query
     * @return org.springblade.core.tool.api.R<com.baomidou.mybatisplus.core.metadata.IPage < com.dhcc.bpm.modules.sandbox.vo.ReturnCodeVO>>
     * @Description 自定义分页 返回码表
     * @Author sjm
     * @Date 21:29 2020/2/21 0021
     **/
    @GetMapping("/page")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "分页", notes = "传入return")
    @ApiLog("分页报文列表")
    @Log(title = "报文列表", businessType = BusinessType.SELECT)
    public R<IPage<ReturnCodeVO>> page(@ApiIgnore ReturnCodeVO returnVo, Query query) {
        IPage<ReturnCodeVO> pages = returnService.selectReturnPage(Condition.getPage(query), returnVo);
        return R.data(pages);
    }

    /**
     * @param returnCode
     * @return org.springblade.core.tool.api.R
     * @Description 新增 返回码表
     * @Author sjm
     * @Date 21:29 2020/2/21 0021
     **/
    @PostMapping("/submitCode")
    @ApiOperationSupport(order = 4)
    @ApiOperation(value = "新增", notes = "传入return")
    @ApiLog("报文新增")
    @Log(title = "报文新增", businessType = BusinessType.INSERT)
    public R save(@Valid @RequestBody ReturnCode returnCode) {
        //设置返回码编号
        String code = serialNumberService.generateSerialNumberByModelCode("opc_return");
        returnCode.setReturnCode(code);
        ReturnCodeVO returnCodeVO = new ReturnCodeVO();
        returnCodeVO.setApiId(returnCode.getApiId());
        List<ReturnCodeVO> list = returnService.selectCodeList(returnCodeVO);
        //插入最后
        if (list != null && list.size() != 0) {
            returnCode.setCodeSort(list.get(0).getMaxOrder() + 1L);
        } else {
            returnCode.setCodeSort(1L);
        }
        return R.status(returnService.save(returnCode));
    }

    /**
     * @param returnCode
     * @return org.springblade.core.tool.api.R
     * @Description 修改 返回码表
     * @Author sjm
     * @Date 21:29 2020/2/21 0021
     **/
    @PostMapping("/update")
    @ApiOperationSupport(order = 5)
    @ApiOperation(value = "修改", notes = "传入return")
    @ApiLog("报文修改")
    @Log(title = "报文修改", businessType = BusinessType.UPDATE)
    public R update(@Valid @RequestBody ReturnCode returnCode) {
        return R.status(returnService.updateById(returnCode));
    }

    /**
     * @param returnCode
     * @return org.springblade.core.tool.api.R
     * @Description 新增或修改 返回码表
     * @Author sjm
     * @Date 21:30 2020/2/21 0021
     **/
    @PostMapping("/submit")
    @ApiOperationSupport(order = 6)
    @ApiOperation(value = "新增或修改", notes = "传入return")
    @ApiLog("报文新增或修改")
    @Log(title = "报文新增或修改", businessType = BusinessType.UPDATE)
    public R submit(@Valid @RequestBody ReturnCode returnCode) {
        if (returnCode.getId() == null) {
            //设置返回码编号
            String code = serialNumberService.generateSerialNumberByModelCode("opc_return");
            returnCode.setReturnCode(code);
            ReturnCodeVO returnCodeVO = new ReturnCodeVO();
            returnCodeVO.setApiId(returnCode.getApiId());
            List<ReturnCodeVO> list = returnService.selectCodeList(returnCodeVO);
            //插入最后
            if (list != null && list.size() != 0) {
                returnCode.setCodeSort(list.get(0).getMaxOrder() + 1L);
            } else {
                returnCode.setCodeSort(1L);
            }
        }
        return R.status(returnService.saveOrUpdate(returnCode));
    }


    /**
     * @param ids
     * @return org.springblade.core.tool.api.R
     * @Description 删除 返回码表
     * @Author sjm
     * @Date 21:30 2020/2/21 0021
     **/
    @PostMapping("/remove")
    @ApiOperationSupport(order = 7)
    @ApiOperation(value = "逻辑删除", notes = "传入ids")
    @ApiLog("报文删除")
    @Log(title = "报文删除", businessType = BusinessType.DELETE)
    public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
        ReturnCode returnCode1 = returnService.getById(Convert.toLongArray(ids)[0]);
        List<String> list = Func.toStrList(ids);
        for (String codeId : list) {
            List<OpcSandboxCodeExpress> dictLis = opcSandboxCodeExpressService.selectByCodeId(codeId);
            for (OpcSandboxCodeExpress opcSandboxCodeExpress : dictLis) {
                opcSandboxCodeExpressService.removeById(opcSandboxCodeExpress.getId());
            }
        }
        if (returnService.deleteLogic(Func.toLongList(ids))) {
            ReturnCode returnCode = new ReturnCode();
            returnCode.setApiId(returnCode1.getApiId());
            QueryWrapper<ReturnCode> queryWrapper = Condition.getQueryWrapper(returnCode);
            List<ReturnCode> codeList = returnService.list(queryWrapper);
            ReturnCode returnCode4 = new ReturnCode();
            Long porder = 1L;
            if (codeList.size() > 0) {
                for (ReturnCode returnCode3 : codeList) {
                    returnCode4.setId(returnCode3.getId());
                    returnCode4.setCodeSort(porder);
                    boolean flagCode = returnService.saveOrUpdate(returnCode4);
                    if (flagCode == false) {
                        return R.status(false);
                    }
                    porder++;
                }
            }
            return R.status(true);
        } else {
            return R.status(false);
        }
    }


    /**
     * @param returnCodeVO
     * @param query
     * @return org.springblade.core.tool.api.R<com.baomidou.mybatisplus.core.metadata.IPage < com.dhcc.bpm.modules.sandbox.vo.ReturnCodeVO>>
     * @Description 自定义分页 报文列表
     * @Author sjm
     * @Date 21:30 2020/2/21 0021
     **/
    @GetMapping("/unInCodeList")
    @ApiOperationSupport(order = 8)
    @ApiOperation(value = "分页", notes = "传入return")
    @Log(title = "查询未分配的报文", businessType = BusinessType.SELECT)
    public R<IPage<ReturnCodeVO>> selectUnReturnList(ReturnCodeVO returnCodeVO, Query query) {
        IPage<ReturnCodeVO> pages = returnService.selectUnReturnList(Condition.getPage(query), returnCodeVO);
        return R.data(pages);
    }

    /**
     * @param returnCode
     * @param query
     * @return org.springblade.core.tool.api.R<com.baomidou.mybatisplus.core.metadata.IPage < com.dhcc.bpm.modules.sandbox.vo.ReturnCodeVO>>
     * @Description 自定义分页  已分配报文列表
     * @Author sjm
     * @Date 21:30 2020/2/21 0021
     **/
    @GetMapping("/selectReTurnCodeList")
    @ApiOperationSupport(order = 9)
    @ApiOperation(value = "分页", notes = "传入return")
    @Log(title = "查询已分配报文列表", businessType = BusinessType.SELECT)
    public R<IPage<ReturnCodeVO>> selectReTurnCodeList(@ApiIgnore ReturnCodeVO returnCode, Query query) {
        IPage<ReturnCodeVO> pages = returnService.selectReTurnCodeList(Condition.getPage(query), returnCode);
        return R.data(pages);
    }

    /**
     * @param returnCodeVO
     * @param query
     * @return org.springblade.core.tool.api.R<com.baomidou.mybatisplus.core.metadata.IPage < com.dhcc.bpm.modules.sandbox.vo.ReturnCodeVO>>
     * @Description 未分配的报文列表
     * @Author sjm
     * @Date 21:30 2020/2/21 0021
     **/
    @GetMapping("/unInCodePage")
    @ApiOperationSupport(order = 10)
    @ApiOperation(value = "分页", notes = "传入return")
    @Log(title = "查询未分配的报文", businessType = BusinessType.SELECT)
    public R<IPage<ReturnCodeVO>> unInCodePage(@ApiIgnore ReturnCodeVO returnCodeVO, Query query) {
        IPage<ReturnCodeVO> pages = returnService.selectUnReturnPage(Condition.getPage(query), returnCodeVO);
        return R.data(pages);
    }

    /**
     * @param apiId
     * @param ids
     * @return org.springblade.core.tool.api.R
     * @Description 批量选择报文
     * @Author sjm
     * @Date 21:30 2020/2/21 0021
     **/
    @PostMapping("/AuthReturnCodeAll")
    @ApiOperationSupport(order = 11)
    @ApiOperation(value = "分页", notes = "传入apiId")
    @Log(title = "批量选择报文", businessType = BusinessType.INSERT)
    public R authReturnCodeAll(@ApiParam(name = "apiId", value = "接口id") @RequestParam Long apiId, @ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
        List<ApiReturn> returnCode = new ArrayList<>();
        List<Long> codeIds = Func.toLongList(ids);
        codeIds.forEach(codeId -> {
            ApiReturn apiReturn = new ApiReturn();
            apiReturn.setApiId(apiId);
            apiReturn.setReturnCodeId(codeId);
            returnCode.add(apiReturn);
        });
        return R.status(apiReturnService.saveBatch(returnCode));
    }

    /**
     * @param apiId
     * @param ids
     * @return org.springblade.core.tool.api.R
     * @Description 批量删除报文
     * @Author sjm
     * @Date 21:31 2020/2/21 0021
     **/
    @PostMapping("/cancelReturnApiAll")
    @ApiOperationSupport(order = 12)
    @ApiOperation(value = "物理删除", notes = "传入ids")
    @Log(title = "批量删除API", businessType = BusinessType.DELETE)
    public R cancelReturnApiAll(@ApiParam(name = "apiId", value = "接口id") @RequestParam Long apiId, @ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
        return R.status(apiReturnService.deleteReturnCode(apiId, ids));
    }

    /**
     * @param returnCode
     * @param query
     * @return org.springblade.core.tool.api.R<com.baomidou.mybatisplus.core.metadata.IPage < com.dhcc.bpm.modules.sandbox.vo.ReturnCodeVO>>
     * @Description 自定义分页  已分配沙箱实例报文列表
     * @Author sjm
     * @Date 21:31 2020/2/21 0021
     **/
    @GetMapping("/selectReTurnCaseList")
    @ApiOperationSupport(order = 13)
    @ApiOperation(value = "分页", notes = "传入return")
    @Log(title = "查询已分配沙箱实例报文列表", businessType = BusinessType.SELECT)
    public R<IPage<ReturnCodeVO>> selectReTurnCaseList(@ApiIgnore ReturnCodeVO returnCode, Query query) {
        IPage<ReturnCodeVO> pages = returnService.selectReTurnCaseList(Condition.getPage(query), returnCode);
        //查询结果为空 自动添加该接口下的报文
        if (pages.getTotal() == 0) {
            List<CaseApiReturn> caseApiReturns = new ArrayList<>();
            ApiReturn code = new ApiReturn();
            code.setApiId(returnCode.getApiId());
            List<ApiReturn> list = apiReturnService.list(Wrappers.query(code));
            list.forEach(data -> {
                CaseApiReturn caseApiReturn = new CaseApiReturn();
                caseApiReturn.setReturnCodeId(data.getReturnCodeId());
                caseApiReturn.setCaseId(returnCode.getCaseId());
                caseApiReturn.setApiId(data.getApiId());
                caseApiReturns.add(caseApiReturn);
            });
            caseApiReturnService.saveBatch(caseApiReturns);
            return R.data(returnService.selectReTurnCaseList(Condition.getPage(query), returnCode));
        } else {
            return R.data(pages);
        }

    }

    /**
     * @param returnCodeVO
     * @param query
     * @return org.springblade.core.tool.api.R<com.baomidou.mybatisplus.core.metadata.IPage < com.dhcc.bpm.modules.sandbox.vo.ReturnCodeVO>>
     * @Description 未分配的沙箱案例报文列表
     * @Author sjm
     * @Date 21:31 2020/2/21 0021
     **/
    @GetMapping("/unInCaseCodePage")
    @ApiOperationSupport(order = 14)
    @ApiOperation(value = "分页", notes = "传入return")
    @Log(title = "查询未分配的沙箱案例报文列表", businessType = BusinessType.SELECT)
    public R<IPage<ReturnCodeVO>> unInCaseCodePage(@ApiIgnore ReturnCodeVO returnCodeVO, Query query) {
        IPage<ReturnCodeVO> pages = returnService.unInCaseCodePage(Condition.getPage(query), returnCodeVO);
        return R.data(pages);
    }

    /**
     * @param apiId
     * @param caseId
     * @param ids
     * @return org.springblade.core.tool.api.R
     * @Description 批量选择沙箱案例报文
     * @Author sjm
     * @Date 21:31 2020/2/21 0021
     **/
    @PostMapping("/AuthReturnCaseAll")
    @ApiOperationSupport(order = 15)
    @ApiOperation(value = "分页", notes = "传入apiId")
    @Log(title = "批量选择沙箱案例报文", businessType = BusinessType.INSERT)
    public R authReturnCaseAll(@ApiParam(name = "apiId", value = "接口id") @RequestParam Long apiId,
                               @ApiParam(name = "caseId", value = "接口id") @RequestParam Long caseId,
                               @ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
        List<CaseApiReturn> caseApiReturns = new ArrayList<>();
        List<Long> codeIds = Func.toLongList(ids);
        codeIds.forEach(codeId -> {
            CaseApiReturn caseApiReturn = new CaseApiReturn();
            caseApiReturn.setApiId(apiId);
            caseApiReturn.setCaseId(caseId);
            caseApiReturn.setReturnCodeId(codeId);
            caseApiReturns.add(caseApiReturn);
        });
        return R.status(caseApiReturnService.saveBatch(caseApiReturns));
    }

    /**
     * @param apiId
     * @param caseId
     * @param ids
     * @return org.springblade.core.tool.api.R
     * @Description 批量删除沙箱案例报文
     * @Author sjm
     * @Date 21:31 2020/2/21 0021
     **/
    @PostMapping("/cancelReturnCaseAll")
    @ApiOperationSupport(order = 16)
    @ApiOperation(value = "物理删除", notes = "传入ids")
    @Log(title = "批量删除沙箱案例报文", businessType = BusinessType.DELETE)
    public R cancelReturnCaseAll(@ApiParam(name = "apiId", value = "接口id") @RequestParam Long apiId,
                                 @ApiParam(name = "caseId", value = "接口id") @RequestParam Long caseId,
                                 @ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
        return R.status(caseApiReturnService.deleteCases(apiId, caseId, ids));
    }

    /**
     * @param apiId
     * @param codeSorts
     * @param flag
     * @param ids
     * @return org.springblade.core.tool.api.R
     * @Description 上移或下移排序
     * @Author sjm
     * @Date 21:31 2020/2/21 0021
     **/
    @PostMapping("/paramOrder")
    @ApiOperationSupport(order = 17)
    @ApiOperation(value = "分页", notes = "传入apiId")
    @Log(title = "修改报文排序", businessType = BusinessType.UPDATE)
    public R paramOrder(@ApiParam(name = "apiId", value = "接口id") @RequestParam Long apiId,
                        @ApiParam(name = "codeSorts", value = "codeSorts") @RequestParam Long codeSorts,
                        @ApiParam(name = "flag", value = "porder") @RequestParam Long flag,
                        @ApiParam(value = "主键集合", required = true) @RequestParam Long ids) {
        ReturnCodeVO returnCode = new ReturnCodeVO();
        ReturnCode returnCode2 = new ReturnCode();
        returnCode.setApiId(apiId);
        Long codeId = null;
        List<ReturnCodeVO> list = returnService.selectCodeList(returnCode);
        if (list != null && list.size() != 0) {
            if (flag == 1L) {
                //上移
                boolean flag2 = false;
                Long preorder = 0L;
                list.add(new ReturnCodeVO());
                for (ReturnCode returnCode3 : list) {
                    if (flag2) {
                        if (preorder.longValue() + 1L == codeSorts.longValue()) {
                            break;
                        }
                    }
                    if (returnCode3.getId().longValue() == ids.longValue()) {
                        flag2 = true;
                    } else {
                        codeId = returnCode3.getId();
                        preorder = returnCode3.getCodeSort();
                    }
                }
            } else {
                //下移
                boolean flag2 = false;
                for (ReturnCode returnCode3 : list) {
                    if (flag2) {
                        if (returnCode3.getCodeSort().longValue() - 1L == codeSorts.longValue()) {
                            codeId = returnCode3.getId();
                        }
                        break;
                    }

                    if (returnCode3.getId().longValue() == ids.longValue()) {
                        flag2 = true;
                    }
                }
            }
            returnCode2.setId(codeId);
            returnCode2.setCodeSort(codeSorts);

        } else {
            return R.status(false);
        }
        if (codeId != null && returnService.saveOrUpdate(returnCode2) == false) {
            return R.status(false);
        }
        returnCode2.setId(ids);
        if (flag == 1L) {
            returnCode2.setCodeSort(codeSorts - 1);
        } else {
            returnCode2.setCodeSort(codeSorts + 1);
        }
        return R.status(returnService.saveOrUpdate(returnCode2));
    }


    @ApiLog("导入excel")
    @ApiOperationSupport(order = 7)
    @ApiOperation(value = "导入excel", notes = "sysNum")
    @Log(title = "导入excel", businessType = BusinessType.SELECT)
    @PostMapping("importExcel")
    public R importExcel(Plupload plupload, HttpServletRequest request) {
        Upload upload = new Upload();
        upload.setRequest(request);
        Upload uploadEntity = pluploadService.getFile(upload);
        MultipartFile file = uploadEntity.getMultipartFile();
        ImportParams importParams = new ImportParams();
        // 数据处理
        //表格标题行数,默认0
        importParams.setHeadRows(1);
        //表头行数,默认1
        importParams.setTitleRows(1);
        ExcelImportResult<ReturnCode> result = null;
        try {
            result = ExcelImportUtil.importExcelMore(file.getInputStream(), ReturnCode.class, importParams);
            List<ReturnCode> list = result.getList();
            if (list.size() > 0) {
                BladeUser user = AuthUtil.getUser();
                list.forEach(returnCode ->{
                    if (user != null) {
                        returnCode.setCreateUser(user.getUserId());
                        returnCode.setCreateDept((Long) Func.toLongList(user.getDeptId()).iterator().next());
                        returnCode.setUpdateUser(user.getUserId());
                    }
                    Date now = DateUtil.now();
                    returnCode.setCreateTime(now);
                    returnCode.setUpdateTime(now);
                    if (returnCode.getStatus() == null) {
                        returnCode.setStatus(1);
                    }

                    returnCode.setIsDeleted(0);
                });
                returnService.saveBatch(list);
            }
        } catch (Exception e) {
            log.error("导入数据失败;{}", e);
            return R.fail("导入失败");
        }
        List<ReturnCode> failList = result.getFailList();
        StringBuilder failMsg = null;
        if (failList.size() < 1) {
            return R.success("导入成功");
        } else {
            failMsg = new StringBuilder();
            for (ReturnCode returnCode : failList) {
                failMsg.append(returnCode.getReturnName()).append(",");
            }
        }
        return R.success("名称为：[" + failMsg.substring(0, failMsg.length() - 1) + "]导入失败");
    }
}
